using System;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Profinet.AllenBradley;

namespace HslCommunication.Profinet.Omron
{
	/// <summary>
	/// 欧姆龙PLC的CIP协议的类，支持NJ,NX,NY系列PLC，支持tag名的方式读写数据，假设你读取的是局部变量，那么使用 Program:MainProgram.变量名<br />
	/// Omron PLC's CIP protocol class, support NJ, NX, NY series PLC, support tag name read and write data, assuming you read local variables, then use Program: MainProgram. Variable name
	/// </summary>
	public class OmronCipNet : AllenBradleyNet
	{
		/// <summary>
		/// Instantiate a communication object for a OmronCipNet PLC protocol
		/// </summary>
		public OmronCipNet()
		{
		}

		/// <summary>
		/// Specify the IP address and port to instantiate a communication object for a OmronCipNet PLC protocol
		/// </summary>
		/// <param name="ipAddress">PLC IpAddress</param>
		/// <param name="port">PLC Port</param>
		public OmronCipNet(string ipAddress, int port = 44818)
			: base(ipAddress, port)
		{
		}

		/// <inheritdoc />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			if (length > 1)
			{
				return Read(new string[1]
				{
					address
				}, new int[1]
				{
					1
				});
			}
			return Read(new string[1]
			{
				address
			}, new int[1]
			{
				length
			});
		}

		/// <inheritdoc />
		public override OperateResult<string> ReadString(string address, ushort length, Encoding encoding)
		{
			OperateResult<byte[]> operateResult = Read(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(operateResult);
			}
			int count = base.ByteTransform.TransUInt16(operateResult.Content, 0);
			return OperateResult.CreateSuccessResult(encoding.GetString(operateResult.Content, 2, count));
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				value = string.Empty;
			}
			byte[] array = SoftBasic.SpliceByteArray(new byte[2], SoftBasic.ArrayExpandToLengthEven(Encoding.ASCII.GetBytes(value)));
			array[0] = BitConverter.GetBytes(array.Length - 2)[0];
			array[1] = BitConverter.GetBytes(array.Length - 2)[1];
			return base.WriteTag(address, 208, array);
		}

		/// <inheritdoc />
		public override OperateResult WriteTag(string address, ushort typeCode, byte[] value, int length = 1)
		{
			return base.WriteTag(address, typeCode, value);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronCipNet.Read(System.String,System.UInt16)" />
		public override async Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			if (length > 1)
			{
				return await ReadAsync(new string[1]
				{
					address
				}, new int[1]
				{
					1
				});
			}
			return await ReadAsync(new string[1]
			{
				address
			}, new int[1]
			{
				length
			});
		}

		/// <inheritdoc />
		public override async Task<OperateResult<string>> ReadStringAsync(string address, ushort length, Encoding encoding)
		{
			OperateResult<byte[]> read = await ReadAsync(address, length);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(read);
			}
			return OperateResult.CreateSuccessResult(encoding.GetString(count: base.ByteTransform.TransUInt16(read.Content, 0), bytes: read.Content, index: 2));
		}

		/// <inheritdoc />
		public override async Task<OperateResult> WriteAsync(string address, string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				value = string.Empty;
			}
			byte[] data = SoftBasic.SpliceByteArray(new byte[2], SoftBasic.ArrayExpandToLengthEven(Encoding.ASCII.GetBytes(value)));
			data[0] = BitConverter.GetBytes(data.Length - 2)[0];
			data[1] = BitConverter.GetBytes(data.Length - 2)[1];
			return await WriteTagAsync(address, 208, data);
		}

		/// <inheritdoc />
		public override async Task<OperateResult> WriteTagAsync(string address, ushort typeCode, byte[] value, int length = 1)
		{
			return await base.WriteTagAsync(address, typeCode, value);
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"OmronCipNet[{IpAddress}:{Port}]";
		}
	}
}
